﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace sqlDALgen.Renderers
{
    public class IfRenderer : IRenderer
    {
        private readonly XmlNode _node;
        private readonly List<Func<String, TemplateData, String>> _switches;
        private readonly XmlNode _exprNode;

        public static IRenderer Get(XmlNode node)
        {
            return new IfRenderer(node);
        }

        public IfRenderer(XmlNode node)
        {
            _node = node;
            _switches = new List<Func<string, TemplateData, string>>();

            #region Switches
            foreach (XmlNode subNode in _node.ChildNodes)
            {
                var subNodeCache = subNode;
                switch (subNode.Name)
                {
                    case "expr":
                        _exprNode = subNode;
                        break;
                    case "equals":
                        _switches.Add((v, d) =>
                        {
                            var reqVal = TemplateRenderer.FillData(subNodeCache.Attributes["value"].Value, d);
                            if (reqVal.Equals(v))
                                return TemplateRenderer.RenderNodeText(subNodeCache, d);

                            return null;
                        });
                        break;
                    case "notEquals":
                        _switches.Add((v, d) =>
                        {
                            var reqVal = TemplateRenderer.FillData(subNodeCache.Attributes["value"].Value, d);
                            if (!reqVal.Equals(v))
                                return TemplateRenderer.RenderNodeText(subNodeCache, d);

                            return null;
                        });
                        break;
                    case "endsWith":
                        _switches.Add((v, d) =>
                        {
                            var reqVal = TemplateRenderer.FillData(subNodeCache.Attributes["value"].Value, d);
                            if (v.EndsWith(reqVal))
                                return TemplateRenderer.RenderNodeText(subNodeCache, d);

                            return null;
                        });
                        break;
                    case "startsWith":
                        _switches.Add((v, d) =>
                        {
                            var reqVal = TemplateRenderer.FillData(subNodeCache.Attributes["value"].Value, d);
                            if (v.StartsWith(reqVal))
                                return TemplateRenderer.RenderNodeText(subNodeCache, d);

                            return null;
                        });
                        break;
                    case "contains":
                        _switches.Add((v, d) =>
                        {
                            var reqVal = TemplateRenderer.FillData(subNodeCache.Attributes["value"].Value, d);
                            if (v.Contains(reqVal))
                                return TemplateRenderer.RenderNodeText(subNodeCache, d);

                            return null;
                        });
                        break;
                    case "else":
                        _switches.Add((v, d) =>
                        {
                            return TemplateRenderer.RenderNodeText(subNodeCache, d);
                        });
                        break;
                }
            }
            #endregion
        }

        public String Render(TemplateData data)
        {
            var builder = new StringBuilder();
            builder.Append(TemplateRenderer.RenderNodeText(_exprNode, data));

            var exprVal = builder.ToString();

            foreach (var sw in _switches)
            {
                var switchVal = sw(exprVal, data);
                if (switchVal != null) return switchVal;
            }

            return exprVal;
        }

        public string FileName
        {
            get { throw new NotImplementedException(); }
        }
    }
}
